package clock.socoolby.com.clock.fragment.spine;

import android.annotation.TargetApi;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.Nullable;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;

import clock.socoolby.com.clock.R;
import com.badlogic.gdx.backends.androidx.AndroidFragmentApplication;

import clock.socoolby.com.clock.widget.spirit.AbstractLibgdxSpineEffectView;
import clock.socoolby.com.clock.widget.spirit.ActionEnum;
import clock.socoolby.com.clock.widget.spirit.ClockStateEnum;


/**
 * Created by QJoy on 2017.12.25.
 */
public class LibgdxSpineFragment extends AndroidFragmentApplication implements InputProcessor {

	public static boolean openDEBUGLog = false;
    private static final String TAG = LibgdxSpineFragment.class.getSimpleName();
    private ViewGroup m_viewRooter = null;

    //粒子效果绘制层
    private AbstractLibgdxSpineEffectView spineEffectView;
    //Fragment 处于销毁过程中标志位
    private boolean m_isDestorying = false;
    //Fragment 处于OnStop标志位
    private boolean m_isStoping = false;
    //Screen 是否需要重建播放
    private boolean m_isNeedBuild =true;

	private boolean m_hasBuilt = false;

    public void preDestory(){

	    if (openDEBUGLog)
	        timber.log.Timber.d("preDestory");

	    if (!m_hasBuilt)
		    return;

	    spineEffectView.forceOver();
	    spineEffectView.setCanDraw(false);

        m_isDestorying = true;
        m_isStoping = true;
    }

    private String spineType;

    public LibgdxSpineFragment(String spineType) {
        this.spineType=spineType;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

	    if (openDEBUGLog)
	        timber.log.Timber.d("onCreateView");

        m_viewRooter = (ViewGroup) inflater.inflate(R.layout.fragment_spine, container,false);
        return m_viewRooter;
    }

	@Override
	public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {

		if (openDEBUGLog)
			timber.log.Timber.d("onViewCreated");

		super.onViewCreated(view, savedInstanceState);
		buildGDX();
	}

    public void buildGDX(){
	    if (openDEBUGLog)
	        timber.log.Timber.d("buildGDX");

        spineEffectView = SpineFactory.build(spineType);
        m_viewRooter.addView(CreateGLAlpha(spineEffectView));
        Gdx.input.setInputProcessor(this);
        Gdx.input.setCatchBackKey(true);
	    m_hasBuilt = true;
    }

    public boolean hasBuilt() {
        return m_hasBuilt;
    }

    @Override
    public void onStart() {

	    if (openDEBUGLog)
            timber.log.Timber.d("onStart");

        m_isStoping = false;
        super.onStart();

	    if (spineEffectView != null)
	        spineEffectView.setCanDraw(true);
    }

    @Override
    public void onStop() {

	    if (openDEBUGLog)
            timber.log.Timber.d("onStop");

        m_isStoping = true;
	    spineEffectView.setCanDraw(false);
        super.onStop();
    }

    @Override
    public void onResume() {

	    if (openDEBUGLog)
            timber.log.Timber.d("onResume");

        super.onResume();

        if(openDEBUGLog)
            setLogLevel(LOG_DEBUG);

	    if (spineEffectView != null) {
		    spineEffectView.closeforceOver();
	    }
    }

    @Override
    public void onPause() {

	    if (openDEBUGLog)
            timber.log.Timber.d("onPause");

	    if (spineEffectView != null) {
		    spineEffectView.forceOver();
	    }

	    super.onPause();
    }

    public void setCanDraw(boolean canDraw){
        if(spineEffectView!=null)
            spineEffectView.setCanDraw(canDraw);
    }

    @Override
    public void onConfigurationChanged(Configuration config) {
	    if (openDEBUGLog)
		    timber.log.Timber.d("onConfigurationChanged");
        super.onConfigurationChanged(config);
        m_viewRooter.removeAllViews();
        buildGDX();
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private View CreateGLAlpha(ApplicationListener application) {

	    if (openDEBUGLog)
		    timber.log.Timber.d("CreateGLAlpha");

        //	    GLSurfaceView透明相关
        AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();
        cfg.r = cfg.g = cfg.b = cfg.a = 8;
        cfg.useAccelerometer=false;
        cfg.useRotationVectorSensor=false;
        cfg.useCompass=false;
        cfg.useGyroscope=false;
        cfg.disableAudio=true;

        View view = initializeForView(application, cfg);

        if (view instanceof SurfaceView) {
            GLSurfaceView glView = (GLSurfaceView) graphics.getView();
            glView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
            glView.setZOrderMediaOverlay(true);
            glView.setZOrderOnTop(true);
        }

        return view;
    }

     public  void setAction(ActionEnum action){
         if (spineEffectView != null) {
             spineEffectView.setAction(action);
         }
     }

     public void setClockState(ClockStateEnum clockState){
         if (spineEffectView != null) {
             spineEffectView.setClockState(clockState);
         }
     }


    public static void setOpenDEBUGLog(boolean openDEBUGLog) {
        LibgdxSpineFragment.openDEBUGLog = openDEBUGLog;
    }

    @Override
    public boolean keyDown(int i) {

	    if (openDEBUGLog)
		    timber.log.Timber.d("keyDown");

        return false;
    }

    AbstractLibgdxSpineEffectView touchSpine=null;

    @Override
    public boolean keyUp(int i) {
        return false;
    }

    @Override
    public boolean keyTyped(char c) {
        return false;
    }

    @Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
        timber.log.Timber.d("touchDown screenX:"+screenX+"\t screenY:"+screenY+"\tpointer:"+pointer+"\tbutton:"+button);

        if(spineEffectView.isContainsPoint(screenX,screenY)) {
            setInterruptTouch(true);
            touchSpine = spineEffectView;
            timber.log.Timber.d("find spine in touch down");
        }
        return false;
    }

    @Override
    public boolean touchUp(int screenX, int screenY, int pointer, int button) {
        timber.log.Timber.d("touchUp screenX:"+screenX+"\t screenY:"+screenY+"\tpointer:"+pointer+"\tbutton:"+button);
        if(touchSpine!=null) {
            touchSpine.setAction(ActionEnum.IDLE);
            setInterruptTouch(false);
        }
        touchSpine=null;
        return false;
    }

    @Override
    public boolean touchDragged(int screenX, int screenY, int pointer) {
        timber.log.Timber.d("touchDragged x:"+screenX+"\t y:"+screenY+"\ti2:"+pointer);
        if(touchSpine!=null) {
            touchSpine.setPosition(screenX,screenY);
            touchSpine.setAction(ActionEnum.RUN);
            //timber.log.Timber.d("touchDragged spine");
        }
	    return false;
    }

    @Override
    public boolean mouseMoved(int x, int y) {
        timber.log.Timber.d("mouseMoved x:"+x+"\t y:"+y);
	    return false;
    }

    @Override
    public boolean scrolled(int amount) {
        timber.log.Timber.d("mouseMoved amount:"+amount);
	    return false;
    }
}
